const Role = require('@/models/role.models')
const Route = require('@/models/route.models')
const RoleRoute = require('@/models/roleRoute.models')
const { createResponse, createErrorResponse } = require('@/utils/tool')

/**
 * 通过ID绑定角色和路由
 * @param {Number} roleId 角色ID
 * @param {Array<Number>} routeIds 路由ID数组
 * @returns 响应对象
 */
async function bindRolesAndRoutes(roleId, routeIds) {
  try {
    // 获取角色
    const role = await Role.findByPk(roleId);
    if (!role) {
      return createErrorResponse({ code: 400, message: `ID ${roleId} 未找到` })
    }

    // 获取指定的路由
    const routes = await Route.findAll({
      where: { id: routeIds }
    });
    if (routes.length !== routeIds.length) {
      return createErrorResponse({ code: 400, message: `路由未找到` })
    }

    // 绑定角色和路由
    await role.setRoutes([]);
    await role.setRoutes(routes);
    return createResponse({ data: routes });
  } catch (error) {
    return createErrorResponse(error)
  }
}



/**
 * 通过角色ID获取关联的路由信息
 * @param {*} roleId 角色ID
 * @returns 响应信息
 */
async function getRoutesByRoleId(roleId) {
  try {
    // 获取角色关联的所有路由ID
    const roleRoutes = await RoleRoute.findAll({
      where: { roleId },
      attributes: ['routeId']
    });

    // 提取路由ID
    const routeIds = roleRoutes.map(route => route.routeId);

    // 获取所有关联的路由信息
    const routes = await Route.findAll({
      where: { id: routeIds },
      order: [['sortOrder', 'ASC']]
    });

    // 重组路由信息
    const tree = buildRouteTree(routes);
    return createResponse({ data: tree });
  } catch (error) {
    return createErrorResponse(error)
  }
}

// 重组路由信息为树形结构
function buildRouteTree(routes) {
  const routeMap = {};
  const tree = [];

  // 创建路由映射
  routes.forEach(route => {
    routeMap[route.id] = { ...route.get(), children: [] };
  });

  // 重组路由信息
  routes.forEach(route => {
    const node = routeMap[route.id];
    if (route.parentId === null) {
      tree.push(node);
    } else {
      const parent = routeMap[route.parentId];
      if (parent) {
        parent.children.push(node);
      }
    }
  });

  return tree;
}

module.exports = { getRoutesByRoleId, bindRolesAndRoutes };